package com.meme.editor.property;

import java.util.Hashtable;

import org.apache.log4j.Logger;

import com.meme.editor.property.value.*;
import com.meme.editor.property.control.*;
import com.meme.util.MiscUtil;

import java.lang.reflect.Constructor;

public class PropertyFactory 
{
	static Logger logger = Logger.getLogger (PropertyFactory.class);
	
	public static final String ValueType_Number = "number";
	public static final String ValueType_String = "string";
	public static final String ValueType_Items   = "items";
	public static final String ValueType_EntityRef   = "entity_ref";
	public static final String ValueType_Boolean   = "boolean";
	
	
	
	public static final String ControlType_Input = "input";
	public static final String ControlType_SelectList = "select_list";
	public static final String ControlType_ChooseFile = "choose_file";
	public static final String ControlType_Number = "number";
	
	
	public static void init ()
	{
		// values
		registerPropertyValueType (ValueType_Number, NumberPropertyValue.class);
		registerPropertyValueType (ValueType_String, StringPropertyValue.class);
		registerPropertyValueType (ValueType_Items, ItemsPropertyValue.class);
		registerPropertyValueType (ValueType_EntityRef, EntityLinkPropertyValue.class);
		registerPropertyValueType (ValueType_Boolean, BoolPropertyValue.class);
		
		// controls
		registerPropertyControlType (ControlType_Input, InputPropertyControl.class);
		registerPropertyControlType (ControlType_SelectList, SelectListPropertyControl.class);
		registerPropertyControlType (ControlType_ChooseFile, FileChooserPropertyControl.class);
		registerPropertyControlType (ControlType_Number, NumberPropertyControl.class);
		
	}

	public static PropertyValue getPropertyValue (String key, Property property)
	{
		Class valueClass = mPropertyValueTypes.get (key);
		
		if ( valueClass == null )
		{
			logger.warn ("ProperyValue [" + key + "] doesn't exist.");
			return null;
		}
		
		try
		{
			Constructor constructor = valueClass.getConstructor(Property.class);
		
			return (PropertyValue) constructor.newInstance(property);
		}
		catch (Exception e)
		{
			logger.error (e);
			
			return null;
		}
	}
	
	public static PropertyControl getPropertyControl (String key)
	{
		Class controlClass = mPropertyControlTypes.get (key);
		
		if ( controlClass == null )
		{
			logger.warn ("PropertyControl [" + key + "] doesn't exist.");
			return null;
		}
		
		try
		{
			Constructor constructor = controlClass.getConstructor();
		
			return (PropertyControl) constructor.newInstance();
		}
		catch (Exception e)
		{
			logger.error (e);
			
			return null;
		}
	}
	
	static Hashtable <String, Class> mPropertyValueTypes = new Hashtable <String, Class> ();
	static Hashtable <String, Class> mPropertyControlTypes = new Hashtable <String, Class> ();
	
	public static void registerPropertyValueType (String key, Class theType)
	{
		logger.assertLog ( MiscUtil.isSubSuperRelation (theType, PropertyValue.class), "Only sub class of PropertyValue can be registered." );
		
		mPropertyValueTypes.put(key, theType);
	}
	
	public static void registerPropertyControlType (String key, Class theType)
	{
		logger.assertLog ( MiscUtil.isSubSuperRelation (theType, PropertyControl.class), "Only sub class of PropertyControl can be registered." );

		mPropertyControlTypes.put(key, theType);
	}
	
}
